/*
 * Copyright (c) 2008, Roman Bosak
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  - Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *  - Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *  - Neither the name of the DailyDevelopment nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */
package com.atlassian.jira.web.action;

import webwork.action.ActionContext;

import com.atlassian.jira.portal.PortalManager;
import com.atlassian.jira.portal.PortalPageConfiguration;
import com.atlassian.jira.portal.PortletConfigurationException;
import com.atlassian.plugin.PluginAccessor;
import com.dailydev.jira.portal.config.IPortalPageSharingConfiguration;
import com.dailydev.jira.portal.config.ISharedPortalPage;

/**
 * Webwork action extending standard Jira {@link Dashboard} action with
 * additional functionalities related to portal page sharing.
 * 
 * @author Roman Bosak, roman.bosak@gmail.com
 */
public class DashboardWithSharing extends Dashboard {

    /**
     * Serial version UID.
     */
    private static final long serialVersionUID = 7855992830580489824L;

    /**
     * Reference to configuration of portal page sharing provided by Jira.
     */
    private final transient IPortalPageSharingConfiguration configuration;

    /**
     * Reference to {@link PortalManager} provided by Jira.
     */
    private final transient PortalManager portalManager;

    /**
     * Constructor for {@link DashboardWithSharing}.
     * 
     * @param portalMgr
     *            reference to {@link PortalManager} instance provided by Jira
     * @param pluginAccessor
     *            reference to {@link PluginAccessor} instance provided by Jira
     * @param sharingConfig
     *            reference to {@link IPortalPageSharingConfiguration} instance
     *            provided by Jira
     */
    public DashboardWithSharing(final PortalManager portalMgr,
            final PluginAccessor pluginAccessor,
            final IPortalPageSharingConfiguration sharingConfig) {
        super(portalMgr, pluginAccessor);
        this.portalManager = portalMgr;
        this.configuration = sharingConfig;
    }

    /**
     * Returns true if current user is author of current portal page, otherwise
     * false.
     * 
     * @return true if current user is author of current portal page, otherwise
     *         false
     * @throws PortletConfigurationException
     *             thrown for same reason as in
     *             {@link Dashboard#getCurrentPageId()}
     */
    public boolean isAuthor() throws PortletConfigurationException {
        Long currentPageId = getCurrentPageId();
        return this.isAuthor(currentPageId);
    }

    /**
     * Returns true if current user is author of portal page specified by
     * <code>portalPageId</code> parameter, otherwise false.
     * 
     * @param portalPageId
     *            ID of the portal page for which we want to check if current
     *            user is it's author
     * @return true if current user is author of portal page specified by
     *         <code>portalPageId</code> parameter, otherwise false
     */
    public boolean isAuthor(final Long portalPageId) {
        ISharedPortalPage sharedDashboard = this.configuration
                .getSharedPortalPage(portalPageId);

        // if the sharedDashboard is null then the portal page is not shared so
        // the user should be author
        if (sharedDashboard == null
                || sharedDashboard.getAuthor()
                        .equals(getRemoteUser().getName())) {
            return true;
        }

        return false;
    }

    /**
     * Conditionally sets status of session parameter
     * 'jira.user.dashboard.configuring' to value of <code>configure</code>
     * parameter. The session parameter can be set to true only if currently
     * selected page is authored by currently logged user and portal page is not
     * a default one. Setting parameter to false is restricted just to not
     * default pages.
     * 
     * @param configure
     *            value to which the session parameter
     *            'jira.user.dashboard.configuring' should be conditionally set
     * @throws PortletConfigurationException
     *             throws for same reason as
     *             {@link PortalManager#getPortalPageConfiguration(com.opensymphony.user.User, Long)}
     * @see com.atlassian.jira.web.action.Dashboard#setConfiguring(boolean)
     */
    @Override
    public void setConfiguring(final boolean configure)
            throws PortletConfigurationException {
        // set configuration to disabled should be available for all pages
        if (!configure) {
            setConfiguringParameter(configure);
        } else {
            PortalPageConfiguration futurePortalPage = getFuturePortalPage();

            // set configuration to true can be possible only for owned and not
            // default pages
            if (this.isAuthor(futurePortalPage.getId())
                    && !futurePortalPage.isDefault()) {
                setConfiguringParameter(configure);
            } else {
                // if the page is not authored or is default it can not be
                // configured - set to false
                setConfiguringParameter(false);
            }
        }
    }

    /**
     * Sets session parameter '<code>jira.user.dashboard.configuring</code>'
     * to value of <code>configure</code>.
     * 
     * @param configure
     *            boolean value to set parameter to
     */
    protected void setConfiguringParameter(final boolean configure) {
        ActionContext.getSession().put("jira.user.dashboard.configuring",
                Boolean.valueOf(configure));
    }

    /**
     * Gets portal page which will be active after the action will be executed.
     * 
     * @return portal page which will be active after the action will be
     *         executed
     * @throws PortletConfigurationException
     *             throws for same reason as
     *             {@link PortalManager#getPortalPageConfiguration(com.opensymphony.user.User, Long)}
     */
    protected PortalPageConfiguration getFuturePortalPage()
            throws PortletConfigurationException {
        PortalPageConfiguration portalPage;
        if (getSelectPageId() != null) {
            portalPage = portalManager.getPortalPageConfiguration(
                    getRemoteUser(), getSelectPageId());
        } else {
            portalPage = getCurrentPortalPage();
        }
        return portalPage;
    }

    /**
     * Sets selected page to page specified by <code>selectPageId</code>
     * parameter. If currently logged user is not an author of the page then
     * also sets configure flag to false.
     * 
     * @param selectPageId
     *            Id of the portal page which is will be selected by this action
     * 
     * @see com.atlassian.jira.web.action.Dashboard#setSelectPageId(java.lang.Long)
     */
    @Override
    public void setSelectPageId(final Long selectPageId) {
        super.setSelectPageId(selectPageId);

        // check if currently logged user is author of the portal page
        if (!this.isAuthor(selectPageId)) {
            // set configuration to false
            this.setConfiguringParameter(false);
        }
    }
}
